<template>
  <div class="common-layout__comment">
    <div>
      <strong style="margin-right: 10px">评论</strong>
      <span>{{ props.commentCount }}</span>
      <div style="position: relative; top: -2px; left: 5px">
        <el-button @click="changeOrderType" :icon="Sort" type="primary" link>
          <span style="position: relative; top: 2px">
            <span v-if="isHot">最热</span>
            <span v-else>最新</span>
          </span>
        </el-button>
      </div>
    </div>
    <el-divider />
    <div
      v-infinite-scroll="appendComments"
      :infinite-scroll-disabled="busyLoadComment"
      class="comment-area-words"
    >
      <div v-for="comment in commentList">
        <div class="comment-avatar">
          <AvatarBackImg
            size="40px"
            :avatar="comment.user.headshot"
          ></AvatarBackImg>
        </div>
        <div>
          <div>
            <strong class="link">{{
              userName(comment.user.name, comment.user.id)
            }}</strong>
            <i>{{ dateConversion(comment.createTime) }}</i>
          </div>
          <p class="text-area">{{ comment.content }}</p>
          <div>
            <span @click="commentLike(comment)" class="link">
              <svg
                class="svg-icon"
                viewBox="0 0 1024 1024"
                width="20"
                height="20"
              >
                <path
                  :fill="comment.isLike ? '#f56c6c' : '#909090'"
                  d="M773.6 912.7h-1.2c-37.2-0.4-74.5-0.4-111.8-0.4h-56.9c-38 0-76 0-114.1-0.5-21.1-0.6-41.9-5-61.5-13-33.3-13-52.3-42-52.2-79.7l0.1-141.4c0-78.3 0-156.7 0.7-235 0.1-21.3 13.8-41.3 25.5-51.8 45.3-41.4 94.5-93 115.1-162.6 5.7-19.4 7.9-40.8 10.2-63.4 4.6-45 33.8-74.3 72.8-74.3 15.3 0 30.6 4.6 45.6 13.5 30.1 18.1 50.2 46.5 61.3 87 17.8 64.3 8.7 126.7-1.3 180.2v0.2c-2.3 12.5 7.1 24.1 19.9 24.1h130c22.4 0 54.5 2.8 74.3 26.8 14.4 17.5 18.5 41.1 12.4 72.3-18.6 95.9-41.4 192.6-63.2 282.7-6.8 28.1-18.1 54.1-29 79.3l-4.7 10.8c-12.4 29.2-38 45.2-72 45.2zM216.1 903.3h-11.9c-43 0-78.2-35.2-78.2-78.2V476.6c0-43 35.2-78.2 78.2-78.2h11.9c43 0 78.2 35.2 78.2 78.2V825c0.1 43.1-35.1 78.3-78.2 78.3z"
                ></path>
              </svg>
              <span>{{ numberConversion(Number(comment.likeCount)) }}</span>
            </span>

            <span
              @click="replyComment(comment)"
              class="link"
              style="color: grey"
              >回复</span
            >
            <el-popconfirm
              confirm-button-text="确认"
              cancel-button-text="算了"
              title="确认删除吗?"
              @confirm="removeComment(comment)"
              v-if="store().userInfo.id === comment.user.id"
            >
              <template #reference>
                <span class="link" style="color: grey">删除</span>
              </template>
            </el-popconfirm>
<!--            <span style="color: grey">举报</span>-->
          </div>
        </div>
        <!-- 子评论 -->
        <div class="comment-area-words">
          <div v-for="sonComment in comment.sonComments">
            <el-divider />
            <div class="comment-avatar">
              <AvatarBackImg
                size="35px"
                :avatar="sonComment.user.headshot"
              ></AvatarBackImg>
            </div>
            <div>
              <div>
                <strong class="link">{{
                  userName(sonComment.user.name, sonComment.user.id)
                }}</strong>
                <i>{{ dateConversion(sonComment.createTime) }}</i>
              </div>
              <p class="text-area">
                <At
                  v-if="!isNull(sonComment.parentId)"
                  :user-name="sonComment.parentUserName"
                  :user-id="sonComment.parentUserId"
                ></At>
                {{ sonComment.content }}
              </p>
              <div>
                <span @click="commentLike(sonComment)" class="link">
                  <svg
                    class="svg-icon"
                    viewBox="0 0 1024 1024"
                    width="20"
                    height="20"
                  >
                    <path
                      :fill="sonComment.isLike ? '#f56c6c' : '#909090'"
                      d="M773.6 912.7h-1.2c-37.2-0.4-74.5-0.4-111.8-0.4h-56.9c-38 0-76 0-114.1-0.5-21.1-0.6-41.9-5-61.5-13-33.3-13-52.3-42-52.2-79.7l0.1-141.4c0-78.3 0-156.7 0.7-235 0.1-21.3 13.8-41.3 25.5-51.8 45.3-41.4 94.5-93 115.1-162.6 5.7-19.4 7.9-40.8 10.2-63.4 4.6-45 33.8-74.3 72.8-74.3 15.3 0 30.6 4.6 45.6 13.5 30.1 18.1 50.2 46.5 61.3 87 17.8 64.3 8.7 126.7-1.3 180.2v0.2c-2.3 12.5 7.1 24.1 19.9 24.1h130c22.4 0 54.5 2.8 74.3 26.8 14.4 17.5 18.5 41.1 12.4 72.3-18.6 95.9-41.4 192.6-63.2 282.7-6.8 28.1-18.1 54.1-29 79.3l-4.7 10.8c-12.4 29.2-38 45.2-72 45.2zM216.1 903.3h-11.9c-43 0-78.2-35.2-78.2-78.2V476.6c0-43 35.2-78.2 78.2-78.2h11.9c43 0 78.2 35.2 78.2 78.2V825c0.1 43.1-35.1 78.3-78.2 78.3z"
                    ></path>
                  </svg>
                  <span>{{
                    numberConversion(Number(sonComment.likeCount))
                  }}</span>
                </span>

                <span
                  @click="replyComment(comment, sonComment)"
                  style="color: grey"
                  class="link"
                  >回复</span
                >
                <el-popconfirm
                  confirm-button-text="确认"
                  cancel-button-text="算了"
                  title="确认删除吗?"
                  @confirm="removeComment(sonComment)"
                  v-if="store().userInfo.id === sonComment.user.id"
                >
                  <template #reference>
                    <span class="link" style="color: grey">删除</span>
                  </template>
                </el-popconfirm>
<!--                <span style="color: grey">举报</span>-->
              </div>
            </div>
          </div>
        </div>
        <span
          v-show="comment.showMore && Number(comment.sonTotal) > 1"
          class="show-all"
        >
          共{{ comment.sonTotal }}条评论,
          <span
            @click="
              () => {
                comment.showMore = false;
                getAllSonComment(comment);
              }
            "
            class="link"
            >点击查看</span
          >
        </span>
        <el-divider />
      </div>
      <el-divider style="opacity: 0" ref="datumWidth" />
      <div class="no-more-tip" v-show="showNoMore">没有更多评论了</div>
      <div class="no-more-tip" v-show="busyLoadComment && !showNoMore">
        客官别急, 正在玩命加载了~~
      </div>
    </div>
    <div style="height: 100px"></div>

    <!-- 评论输入框 -->
    <el-affix target=".comment-area-words" position="bottom" :offset="0">
      <div :style="inputStyle" class="comment-input">
        <div>
          <el-input
            v-model="inputComment.content"
            resize="none"
            type="textarea"
            :placeholder="inputPlaceholder"
            show-word-limit
            maxlength="1400"
            ref="commentInputArea"
          />
          <div class="link" @click="refreshInput">
            <el-icon size="20">
              <RefreshLeft />
            </el-icon>
          </div>
        </div>
        <el-button
          @click="sendComment"
          :icon="Position"
          type="primary"
          circle
        />
      </div>
    </el-affix>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, watch, onBeforeUnmount } from "vue";
import { Position, Sort, RefreshLeft } from "@element-plus/icons-vue";
import commentApi from "@/api/comment";
import commonApi from "@/api/common";
import likeApi from "@/api/like";
import {
  isNull,
  numberConversion,
  dateConversion,
  successNotify,
  errorNotify,
  userName,
  getBackImg,
} from "@/utils/common";
import { useRoute } from "vue-router";
import store from "@/store/store";
import At from "@/components/At.vue";
import { Comment, CommentSave } from "@/types/comment";
import AvatarBackImg from "@/components/AvatarBackImg.vue";

const props = defineProps(["commentCount"]);
const route = useRoute();

const pageIndex = ref<number>(1);
const pageSize = ref<number>(5);
const isHot = ref<boolean>(true);
const commentList = ref<Comment[]>([]);
const showNoMore = ref<boolean>(false);
const inputStyle = ref({}); // input框样式
const inputPlaceholder = ref<string>("元芳, 你怎么看?");
const busyLoadComment = ref<boolean>(false); // 同步化 获取评论信息
const parentNameForNewComment = ref<string>("");
const commentInputArea = ref<HTMLElement>(); // 评论框对象
const inputComment = ref(<CommentSave>{});
// 当前回复的评论所在的list区, 用来控制添加评论时, 新评论插入的位置
// 默认在根评论区, 点击下方的 '回复' 更换
const nowReply = ref();

// 切换评论排序方式, 最热 -- 最新
const changeOrderType = () => {
  isHot.value = !isHot.value;
  refreshComment();
};
// 刷新评论区
const refreshComment = () => {
  pageIndex.value = 1;
  showNoMore.value = false;
  commentList.value = [];
  appendComments();
};

// 分页查询评论数据, 追加到commentList
const appendComments = async () => {
  busyLoadComment.value = true;
  // 显示了noMore, 就不再请求后端数据了
  if (!showNoMore.value) {
    let params = {
      videoId: route.params.id + "",
      pageIndex: pageIndex.value,
      pageSize: pageSize.value,
      isHot: isHot.value,
    };
    commentApi.getByVideoId(params).then((res) => {
      busyLoadComment.value = false;
      if (res.data.code === 0) {
        let data: Comment[] = res.data.data;
        if (data.length === 0) {
          showNoMore.value = true;
        } else {
          // 获得的数据新增字段showMore, 用于子评论数超过3个时, 显示'查看更多',
          // 点击'查看更多'后, showMore设置为false, '查看更多'则消失
          data.forEach((item) => {
            item.showMore = true;
          });
          commentList.value = commentList.value.concat(data);
          pageIndex.value = pageIndex.value + 1;
        }
      }
    });
  }
};
// 发送评论
const sendComment = () => {
  if (!isNull(inputComment.value.content)) {
    commentApi.save(inputComment.value).then((res) => {
      if (res.data.code === 0) {
        let cmtSave: Comment = res.data.data;
        // 开头显示自己的评论
        cmtSave.user = store().userInfo;
        if (!isNull(parentNameForNewComment.value))
          cmtSave.parentUserName = parentNameForNewComment.value;
        // 选择在哪儿插入新评论, 根评论上 还是子评论上
        if (isNull(nowReply.value)) {
          commentList.value = [cmtSave, ...commentList.value];
        } else {
          // TypeError: 'x' is not iterable
          if (isNull(nowReply.value.sonComments)) {
            nowReply.value.sonComments = [cmtSave];
          } else {
            nowReply.value.sonComments = [
              cmtSave,
              ...nowReply.value.sonComments,
            ];
          }
        }
        // 重置评论框
        refreshInput();
      }
    });
  } else {
    inputComment.value.content = "";
    errorNotify("特灭, 你到底在说什么!");
  }
};
// 回复评论, 设置请求数据
const replyComment = (rootComment: Comment, parentComment?: Comment) => {
  // 更换新评论添加的位置
  nowReply.value = rootComment;

  // 设置根评论id
  inputComment.value.rootId = rootComment.id;
  // 若是回复二级以下的评论
  if (typeof parentComment !== "undefined") {
    parentNameForNewComment.value = parentComment.user.name;
    inputComment.value.parentId = parentComment.id;
    inputPlaceholder.value =
      "@" + userName(parentComment.user.name, parentComment.user.id) + ":";
  } else {
    inputPlaceholder.value =
      "@" + userName(rootComment.user.name, rootComment.user.id) + ":";
  }
  // 聚焦输入框
  commentInputArea.value?.focus();
};

// 获取所有子评论
const getAllSonComment = (parent: Comment) => {
  commentApi.getAllSons(parent.id).then((res) => {
    if (res.data.code === 0) {
      parent.sonComments = res.data.data;
    }
  });
};

// 重置评论框
const refreshInput = () => {
  nowReply.value = null;
  inputPlaceholder.value = "元芳, 你怎么看?";
  parentNameForNewComment.value = "";
  inputComment.value = {
    content: "",
    videoId: route.params.id + "",
  };
};

// 删除自己的评论
const removeComment = async (comment: Comment) => {
  const { code, data } = await commentApi.remove([comment.id]);
  if (code === 0) {
    successNotify(data);
    refreshComment();
  }
};

// 点赞评论
const commentLike = (comment: Comment) => {
  likeApi.likeComment(comment.id, comment.isLike).then((res) => {
    if (res.data.code === 0) {
      comment.isLike = !comment.isLike;
      comment.likeCount =
        (comment.isLike
          ? parseInt(comment.likeCount) + 1
          : parseInt(comment.likeCount) - 1) + "";
    }
  });
};

const watchRoute = watch(
  () => route.params.id,
  (val) => {
    inputComment.value = {
      content: "",
      videoId: val + "",
    };
    refreshComment();
  },
  { immediate: true }
);

onUnmounted(() => {
  watchRoute();
});
</script>

<style lang="scss" scoped>
.common-layout__comment {
  padding: 30px 30px 30px 60px;

  & > div:first-child {
    display: flex;
    position: relative;
    left: -30px;

    & > div {
      position: relative;
      top: -5px;
      left: 5px;
    }
  }

  .comment-area-words {
    & > div {
      position: relative;

      .comment-avatar {
        position: absolute;
        left: -60px;
      }
    }

    strong {
      font-size: 15px;
      color: #6e6e6e;
    }

    i {
      font-size: 13px;
      margin-left: 10px;
    }

    p {
      font-size: 15px;
      margin-top: 10px;
      margin-bottom: 10px;
    }

    span {
      margin-left: 5px;
      margin-right: 20px;
      font-size: 14px;
    }

    .comment-area-words {
      position: relative;
      left: 60px;
      width: calc(100% - 60px);

      & + .show-all {
        position: relative;
        top: 15px;
        font-size: 15px;
        color: #676767;
      }
    }
  }

  .no-more-tip {
    color: grey;
    text-align: center;
  }

  .comment-input {
    height: 60px;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    border: 1px solid #e7e7e7;
    background-color: #f3f3f3;
    border-radius: 10px;

    & > div {
      width: 85%;
      position: relative;

      & > div:last-child {
        position: absolute;
        top: 2px;
        right: 10px;
      }
    }
  }

  .svg-icon {
    position: relative;
    top: 2px;
  }
}
</style>

<style lang="scss">
.comment-input__comment {
  textarea {
    box-shadow: none;

    &::-webkit-scrollbar {
      background-color: rgba(255, 255, 255, 0);
    }

    &::-webkit-scrollbar-thumb {
      background-color: rgba(182, 171, 171, 0);
    }
  }
}
</style>
